package 栈.数组模拟栈.中缀转后缀;

import java.util.ArrayList;
import java.util.List;
import java.util.Stack;

public class PolandCalculator {
    public static void main(String[] args) {
        String input = "1+(2+3*4)-3";
        List<String> list = infixToListparseSuf(input);
        List<String> suffixList = parseSuffixExpressionListparseSuf(list);
        int res = calculatePriority(suffixList);
        System.out.println(res);
    }

    public static List<String> infixToListparseSuf(String input){
        ArrayList<String> list = new ArrayList<>();
        int i = 0;
        String str = "";
        char c;
        do{
            if ((c = input.charAt(i)) < 48 || (c = input.charAt(i)) > 57) { // 如果是运算符
                list.add(""+c);
                i++;
            }else {
                str = "";
                while (i < input.length() && (c = input.charAt(i)) >= 48 && (c = input.charAt(i)) <= 57) {
                    str += c;
                    i++;
                }
                list.add(str);
            }
        }while (i<input.length());
        return list;
    }

    /**
     * 中缀转后缀
     * @param list
     * @return
     */
    public static List<String> parseSuffixExpressionListparseSuf(List<String> list) {
        Stack<String> stack = new Stack<>();
        ArrayList<String> queue = new ArrayList<>();

        for (String item : list) {
            if (item.matches("\\d+")) { // 凡是遍历到数字就放到list中
                queue.add(item);
            }
            if ("(".equals(item)) { // 凡是（ 就压栈
                stack.push(item);
            }
            if (")".equals(item)) {
                while (!"(".equals(stack.peek())) { // 凡不是（也就是右括号就弹出栈顶运算符压入s2，直到遇到（为止。消除（）括号
                    queue.add(stack.pop());
                }
                stack.pop();
            }
            if (!item.matches("\\d+")) {
                // 如果当前运算符小于栈顶运算符优先级
                while (stack.size() != 0 && Operation.getPriority(item) <= Operation.getPriority(stack.peek())) {
                    queue.add(stack.pop()); // 栈顶的优先级高必须先弹出去s2
                }
                stack.push(item);
            }
        }
        while (stack.size() != 0) {
            queue.add(stack.pop());
        }
        return queue;
    }

    /**
     * 计算后缀表达式最终运算结果
     * @param suffic
     * @return
     */
    public static int calculatePriority(List<String> suffic) {
        Stack<String> stack = new Stack<>();
        for (String item : suffic) {
            if (item.matches("\\d+")) {
                stack.push(item);
            }
            if (!item.matches("\\d+")) {
                int num2 = Integer.parseInt(stack.pop());
                int num1 = Integer.parseInt(stack.pop());
                int res = 0;
                if ("+".equals(item)) {
                    res = num1 + num2;
                }
                if ("-".equals(item)) {
                    res = num1-num2;
                }
                if ("*".equals(item)) {
                    res = num1*num2;
                }
                if ("/".equals(item)) {
                    res = num1/num2;
                }
                stack.push(""+res);
            }
        }
        return Integer.parseInt(stack.pop());
    }
}

class Operation {

    public static int getPriority(String opert) {
        int level = 0;
        switch (opert) {
            case "+":
                level = 1;
                break;
            case "-":
                level = 1;
                break;
            case "*":
                level = 2;
                break;
            case "/":
                level = 2;
                break;
        }
        return level;

    }
}
